<!DOCTYPE HTML>
<html>

<head>
	<link rel="bookmark"  type="image/x-icon"  href="/img/logo_miccall.png"/>
	<link rel="shortcut icon" href="/img/logo_miccall.png">
	
			    <title>
    Ame雨
    </title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
    <link rel="stylesheet" href="/amelin-ting/css/mic_main.css" />
    <link rel="stylesheet" href="/amelin-ting/css/dropdownMenu.css" />
    <meta name="keywords" content="Ame雨" />
    
    	<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
	 
    <noscript>
        <link rel="stylesheet" href="/amelin-ting/css/noscript.css" />
    </noscript>
    <style type="text/css">
        body:before {
          content: ' ';
          position: fixed;
          top: 0;
          background: url('/amelin-ting/img/bg.jpg') center 0 no-repeat;
          right: 0;
          bottom: 0;
          left: 0;
          background-size: cover; 
        }
    </style>

			    
  
    <script type="text/x-mathjax-config">
      MathJax.Hub.Config({
        tex2jax: {
          inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
          processEscapes: true,
          skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
        }
      });
    </script>

    <script type="text/x-mathjax-config">
      MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for (i=0; i < all.length; i += 1) {
          all[i].SourceElement().parentNode.className += ' has-jax';
        }
      });
    </script>
    <script async type="text/javascript" src="//cdn.bootcss.com/mathjax/2.7.1/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
  


    <script src="/amelin-ting/js/jquery.min.js"></script>
    <script src="/amelin-ting/js/jquery.scrollex.min.js"></script>
    <script src="/amelin-ting/js/jquery.scrolly.min.js"></script>
    <script src="/amelin-ting/js/skel.min.js"></script>
    <script src="/amelin-ting/js/util.js"></script>
    <script src="/amelin-ting/js/main.js"></script>
	
<meta name="generator" content="Hexo 5.4.0"></head>
    
		
<!-- Layouts -->



<!--  代码渲染  -->
<link rel="stylesheet" href="/css/prism_coy.css" />
<link rel="stylesheet" href="/css/typo.css" />
<!-- 文章页 -->
<body class="is-loading">
    <!-- Wrapper 外包 s-->
    <div id="wrapper" class="fade-in">
        <!-- Intro 头部显示 s -->
        <!-- Intro 头部显示 e -->
        <!-- Header 头部logo start -->
        <header id="header">
    <a href="/amelin-ting/" class="logo">Art Space</a>
</header>
        <!-- Nav 导航条 start -->
        <nav id="nav" class="special" >
            <ul class="menu links" >
			<!-- Homepage  主页  --> 
			<li >
	            <a href="/amelin-ting/" rel="nofollow">主页</a>
	        </li>
			<!-- categories_name  分类   --> 
	        
	        <li class="active">
	            <a href="#s1">分类</a>
	                    <ul class="submenu">
	                        <li>
	                        <a class="category-link" href="/amelin-ting/categories/Go/">Go</a></li><li><a class="category-link" href="/amelin-ting/categories/django/">django</a></li><li><a class="category-link" href="/amelin-ting/categories/drf/">drf</a></li><li><a class="category-link" href="/amelin-ting/categories/gin/">gin</a></li><li><a class="category-link" href="/amelin-ting/categories/go/">go</a></li><li><a class="category-link" href="/amelin-ting/categories/linux/">linux</a></li><li><a class="category-link" href="/amelin-ting/categories/mysql/">mysql</a></li><li><a class="category-link" href="/amelin-ting/categories/python/">python</a></li><li><a class="category-link" href="/amelin-ting/categories/%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F/">内网穿透</a></li><li><a class="category-link" href="/amelin-ting/categories/%E5%89%8D%E7%AB%AF/">前端</a>
	                    </ul>
	        </li>
	        
	        <!-- archives  归档   --> 
	        
	        
		        <!-- Pages 自定义   -->
		        
		        <li>
		            <a href="/about/" title="简历">
		                简历
		            </a>
		        </li>
		        
		        <li>
		            <a href="/group/" title="团队">
		                团队
		            </a>
		        </li>
		        
		        <li>
		            <a href="/gallery/" title="图库">
		                图库
		            </a>
		        </li>
		        
		        <li>
		            <a href="/tag/" title="标签">
		                标签
		            </a>
		        </li>
		        


            </ul>
            <!-- icons 图标   -->
			<ul class="icons">
                    
                    <li>
                        <a title="github" href="https://github.com/miccall" target="_blank" rel="noopener">
                            <i class="icon fa fa-github"></i>
                        </a>
                    </li>
                    
                    <li>
                        <a title="500px" href="http://500px.com" target="_blank" rel="noopener">
                            <i class="icon fa fa-500px"></i>
                        </a>
                    </li>
                    
			</ul>
</nav>

        <div id="main" >
            <div class ="post_page_title_img" style="height: 25rem;background-image: url(https://img1.baidu.com/it/u=3240540933,2717644216&amp;fm=253&amp;fmt=auto&amp;app=138&amp;f=JPEG?w=500&amp;h=281);background-position: center; background-repeat:no-repeat; background-size:cover;-moz-background-size:cover;overflow:hidden;" >
                <a href="#" style="padding: 4rem 4rem 2rem 4rem ;"><h2 >Go-gin</h2></a>
            </div>
            <!-- Post -->
            <div class="typo" style="padding: 3rem;">
                <h2 id="一、返回JSON数据"><a href="#一、返回JSON数据" class="headerlink" title="一、返回JSON数据"></a>一、返回JSON数据</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1.</span> 利用<span class="keyword">map</span></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">        r := gin.Default() <span class="comment">// 默认路由引擎</span></span><br><span class="line"></span><br><span class="line">        r.Static(<span class="string">&quot;/xxx&quot;</span>, <span class="string">&quot;./static&quot;</span>)</span><br><span class="line"></span><br><span class="line">        r.LoadHTMLFiles(<span class="string">&quot;template/index.html&quot;</span>) <span class="comment">// 模板解析</span></span><br><span class="line"></span><br><span class="line">        r.GET(<span class="string">&quot;/json&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">            <span class="comment">// 使用map</span></span><br><span class="line">            <span class="comment">//data := map[string]interface&#123;&#125; &#123;</span></span><br><span class="line">            <span class="comment">//	&quot;name&quot;: &quot;Ame&quot;,</span></span><br><span class="line">            <span class="comment">//	&quot;msg&quot;: &quot;hello world&quot;,</span></span><br><span class="line">            <span class="comment">//	&quot;age&quot;: 18,</span></span><br><span class="line">            <span class="comment">//&#125;</span></span><br><span class="line">            data := gin.H&#123;</span><br><span class="line">                <span class="string">&quot;name&quot;</span>: <span class="string">&quot;Ame&quot;</span>,</span><br><span class="line">                <span class="string">&quot;msg&quot;</span>:  <span class="string">&quot;hello world&quot;</span>,</span><br><span class="line">                <span class="string">&quot;age&quot;</span>:  <span class="number">18</span>,</span><br><span class="line">            &#125; <span class="comment">// gin.H 就是gin给你准备了跟上面一样的map</span></span><br><span class="line">            c.JSON(http.StatusOK, data)</span><br><span class="line">        &#125;)</span><br><span class="line"></span><br><span class="line">        r.Run()</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="number">2.</span> 利用结构体</span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">        r := gin.Default() <span class="comment">// 默认路由引擎</span></span><br><span class="line"></span><br><span class="line">        r.Static(<span class="string">&quot;/xxx&quot;</span>, <span class="string">&quot;./static&quot;</span>)</span><br><span class="line"></span><br><span class="line">        r.LoadHTMLFiles(<span class="string">&quot;template/index.html&quot;</span>) <span class="comment">// 模板解析</span></span><br><span class="line"></span><br><span class="line">        r.GET(<span class="string">&quot;/json&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">            <span class="keyword">type</span> user <span class="keyword">struct</span> &#123; <span class="comment">// 注意要字段一定首字母大写，表示公开状态</span></span><br><span class="line">                Name <span class="keyword">string</span> <span class="string">`json:&quot;name&quot;`</span>  <span class="comment">// 合理运用Tag和反射</span></span><br><span class="line">                Age <span class="keyword">int</span></span><br><span class="line">                Msg <span class="keyword">string</span></span><br><span class="line">            &#125;</span><br><span class="line">            user1 := user&#123;</span><br><span class="line">                <span class="string">&quot;Ame&quot;</span>,</span><br><span class="line">                <span class="number">18</span>,</span><br><span class="line">                <span class="string">&quot;hello world&quot;</span>,</span><br><span class="line">            &#125;</span><br><span class="line">            c.JSON(http.StatusOK, user1)</span><br><span class="line">        &#125;)</span><br><span class="line"></span><br><span class="line">        r.Run()</span><br><span class="line">    &#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="二、gin获取querystring参数"><a href="#二、gin获取querystring参数" class="headerlink" title="二、gin获取querystring参数"></a>二、gin获取querystring参数</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1.</span> 什么是querystring</span><br><span class="line">	就是GET方式请求的url后面?跟的参数   web/json/?query=<span class="string">&quot;lala&quot;</span>&amp;age=<span class="string">&quot;18&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="number">2.</span> 代码演示</span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">        r := gin.Default() <span class="comment">// 默认路由引擎</span></span><br><span class="line"></span><br><span class="line">        r.Static(<span class="string">&quot;/xxx&quot;</span>, <span class="string">&quot;./static&quot;</span>)</span><br><span class="line"></span><br><span class="line">        r.LoadHTMLFiles(<span class="string">&quot;template/index.html&quot;</span>) <span class="comment">// 模板解析</span></span><br><span class="line"></span><br><span class="line">        r.GET(<span class="string">&quot;/index&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">            <span class="comment">// 第一种方法</span></span><br><span class="line">            name := c.Query(<span class="string">&quot;query&quot;</span>)</span><br><span class="line">            age := c.Query(<span class="string">&quot;age&quot;</span>) <span class="comment">// 多个参数就写多句代码</span></span><br><span class="line">            c.JSON(http.StatusOK, gin.H&#123;</span><br><span class="line">                <span class="string">&quot;name&quot;</span>: name,</span><br><span class="line">                <span class="string">&quot;age&quot;</span>: age,</span><br><span class="line">            &#125;)</span><br><span class="line">            <span class="comment">// 剩余方法介绍</span></span><br><span class="line">            c.QueryArray()  <span class="comment">// 返回切片</span></span><br><span class="line">            c.QueryMap()  <span class="comment">// 返回map</span></span><br><span class="line">            c.DefaultQuery()  <span class="comment">// 读的到就返回数据，没有就返回设置的默认值</span></span><br><span class="line">            c.GetQuery() <span class="comment">// 读的到返回数据和true，没有就返回false</span></span><br><span class="line">        &#125;)</span><br><span class="line">        r.Run()</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<h2 id="三、gin获取form参数"><a href="#三、gin获取form参数" class="headerlink" title="三、gin获取form参数"></a>三、gin获取form参数</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// html</span></span><br><span class="line">    &lt;!doctype html&gt;</span><br><span class="line">    &lt;html lang=<span class="string">&quot;en&quot;</span>&gt;</span><br><span class="line">    &lt;head&gt;</span><br><span class="line">        &lt;meta charset=<span class="string">&quot;UTF-8&quot;</span>&gt;</span><br><span class="line">        &lt;meta name=<span class="string">&quot;viewport&quot;</span></span><br><span class="line">              content=<span class="string">&quot;width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0&quot;</span>&gt;</span><br><span class="line">        &lt;meta http-equiv=<span class="string">&quot;X-UA-Compatible&quot;</span> content=<span class="string">&quot;ie=edge&quot;</span>&gt;</span><br><span class="line">        &lt;title&gt;Document&lt;/title&gt;</span><br><span class="line">    &lt;/head&gt;</span><br><span class="line">    &lt;body&gt;</span><br><span class="line">    &lt;form action=<span class="string">&quot;/login&quot;</span> method=<span class="string">&quot;post&quot;</span>&gt;</span><br><span class="line">        &lt;div&gt;</span><br><span class="line">            &lt;label <span class="keyword">for</span>=<span class="string">&quot;username&quot;</span>&gt;&lt;/label&gt;账号：</span><br><span class="line">            &lt;input <span class="keyword">type</span>=<span class="string">&quot;text&quot;</span> id=<span class="string">&quot;username&quot;</span> name=<span class="string">&quot;username&quot;</span>&gt;</span><br><span class="line">        &lt;/div&gt;</span><br><span class="line">        &lt;div&gt;</span><br><span class="line">            &lt;label <span class="keyword">for</span>=<span class="string">&quot;password&quot;</span>&gt;&lt;/label&gt;密码：</span><br><span class="line">            &lt;input <span class="keyword">type</span>=<span class="string">&quot;password&quot;</span> id=<span class="string">&quot;password&quot;</span> name=<span class="string">&quot;password&quot;</span>&gt;</span><br><span class="line">        &lt;/div&gt;</span><br><span class="line">        &lt;div&gt;</span><br><span class="line">            &lt;button <span class="keyword">type</span>=<span class="string">&quot;submit&quot;</span>&gt;登录&lt;/button&gt;</span><br><span class="line">        &lt;/div&gt;</span><br><span class="line">    &lt;/form&gt;</span><br><span class="line">    &lt;/body&gt;</span><br><span class="line">    &lt;/html&gt;</span><br><span class="line"></span><br><span class="line"><span class="comment">// index.tmpl</span></span><br><span class="line">    &lt;!doctype html&gt;</span><br><span class="line">    &lt;html lang=<span class="string">&quot;en&quot;</span>&gt;</span><br><span class="line">    &lt;head&gt;</span><br><span class="line">        &lt;meta charset=<span class="string">&quot;UTF-8&quot;</span>&gt;</span><br><span class="line">        &lt;meta name=<span class="string">&quot;viewport&quot;</span></span><br><span class="line">              content=<span class="string">&quot;width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0&quot;</span>&gt;</span><br><span class="line">        &lt;meta http-equiv=<span class="string">&quot;X-UA-Compatible&quot;</span> content=<span class="string">&quot;ie=edge&quot;</span>&gt;</span><br><span class="line">        &lt;title&gt;Document&lt;/title&gt;</span><br><span class="line">    &lt;/head&gt;</span><br><span class="line">    &lt;body&gt;</span><br><span class="line">    &lt;h1&gt;&#123;&#123; .Name &#125;&#125;&lt;/h1&gt;</span><br><span class="line">    &lt;h1&gt;&#123;&#123; .Password &#125;&#125;&lt;/h1&gt;</span><br><span class="line">    &lt;/body&gt;</span><br><span class="line">    &lt;/html&gt;</span><br><span class="line"></span><br><span class="line"><span class="comment">// main.go</span></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">        r := gin.Default() <span class="comment">// 默认路由引擎</span></span><br><span class="line"></span><br><span class="line">        r.Static(<span class="string">&quot;/xxx&quot;</span>, <span class="string">&quot;./static&quot;</span>)</span><br><span class="line"></span><br><span class="line">        r.LoadHTMLFiles(<span class="string">&quot;template/login.html&quot;</span>, <span class="string">&quot;template/index.tmpl&quot;</span>) <span class="comment">// 模板解析</span></span><br><span class="line"></span><br><span class="line">        r.GET(<span class="string">&quot;/login&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">            c.HTML(http.StatusOK, <span class="string">&quot;login.html&quot;</span>, <span class="literal">nil</span>)</span><br><span class="line">        &#125;)</span><br><span class="line"></span><br><span class="line">        r.POST(<span class="string">&quot;/login&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">            username := c.PostForm(<span class="string">&quot;username&quot;</span>)</span><br><span class="line">            password := c.PostForm(<span class="string">&quot;password&quot;</span>)</span><br><span class="line">            <span class="comment">// 也有其他的方法 跟返回Querystring的方法意思是一样的</span></span><br><span class="line">            c.HTML(http.StatusOK, <span class="string">&quot;index.tmpl&quot;</span>, gin.H&#123;</span><br><span class="line">                <span class="string">&quot;Name&quot;</span>: username,</span><br><span class="line">                <span class="string">&quot;Password&quot;</span>: password,</span><br><span class="line">            &#125;)</span><br><span class="line">        &#125;)</span><br><span class="line"></span><br><span class="line">        r.Run()</span><br><span class="line">    &#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="四、gin参数绑定"><a href="#四、gin参数绑定" class="headerlink" title="四、gin参数绑定"></a>四、gin参数绑定</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">为了能够更方便的获取请求相关参数，提高开发效率，我们可以基于请求的Content-Type识别请求数据类型并利用反射机制自动提取请求中QueryString、form表单、JSON、XML等参数到结构体中。.ShouldBind()强大的功能，它能够基于请求自动提取JSON、form表单和QueryString类型的数据，并把值绑定到指定的结构体对象。</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> UserInfo <span class="keyword">struct</span> &#123;</span><br><span class="line">	Username <span class="keyword">string</span> <span class="string">`form:&quot;username&quot; json:&quot;username&quot;`</span></span><br><span class="line">	Password <span class="keyword">string</span> <span class="string">`form:&quot;password&quot; json:&quot;password&quot;`</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">	r := gin.Default() <span class="comment">// 默认路由引擎</span></span><br><span class="line"></span><br><span class="line">	r.GET(<span class="string">&quot;/user&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">		<span class="keyword">var</span> user UserInfo</span><br><span class="line">		err := c.ShouldBind(&amp;user)</span><br><span class="line">		<span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">			c.JSON(http.StatusBadRequest, gin.H&#123;</span><br><span class="line">				<span class="string">&quot;error&quot;</span>: err,</span><br><span class="line">			&#125;)</span><br><span class="line">		&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">			fmt.Printf(<span class="string">&quot;%#v&quot;</span>, user)</span><br><span class="line">			c.JSON(http.StatusOK, gin.H&#123;</span><br><span class="line">				<span class="string">&quot;status&quot;</span>: <span class="string">&quot;ok&quot;</span>,</span><br><span class="line">			&#125;)</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;)</span><br><span class="line"></span><br><span class="line">	r.Run(<span class="string">&quot;:9090&quot;</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">ShouldBind会按照下面的顺序解析请求中的数据完成绑定：</span></span><br><span class="line"><span class="comment">    如果是 GET 请求，只使用 Form 绑定引擎（query）。</span></span><br><span class="line"><span class="comment">    如果是 POST 请求，首先检查 content-type 是否为 JSON 或 XML，然后再使用 Form（form-data）</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>

<h2 id="五、文件上传"><a href="#五、文件上传" class="headerlink" title="五、文件上传"></a>五、文件上传</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 单个文件上传</span></span><br><span class="line"></span><br><span class="line">前端页面代码：</span><br><span class="line">    &lt;!DOCTYPE html&gt;</span><br><span class="line">    &lt;html lang=<span class="string">&quot;zh-CN&quot;</span>&gt;</span><br><span class="line">    &lt;head&gt;</span><br><span class="line">        &lt;title&gt;上传文件示例&lt;/title&gt;</span><br><span class="line">    &lt;/head&gt;</span><br><span class="line">    &lt;body&gt;</span><br><span class="line">    &lt;form action=<span class="string">&quot;/upload&quot;</span> method=<span class="string">&quot;post&quot;</span> enctype=<span class="string">&quot;multipart/form-data&quot;</span>&gt;</span><br><span class="line">        &lt;input <span class="keyword">type</span>=<span class="string">&quot;file&quot;</span> name=<span class="string">&quot;f1&quot;</span>&gt;</span><br><span class="line">        &lt;input <span class="keyword">type</span>=<span class="string">&quot;submit&quot;</span> value=<span class="string">&quot;上传&quot;</span>&gt;</span><br><span class="line">    &lt;/form&gt;</span><br><span class="line">    &lt;/body&gt;</span><br><span class="line">    &lt;/html&gt;</span><br><span class="line">后端gin框架部分代码：</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">        router := gin.Default()</span><br><span class="line">        <span class="comment">// 处理multipart forms提交文件时默认的内存限制是32 MiB</span></span><br><span class="line">        <span class="comment">// 可以通过下面的方式修改</span></span><br><span class="line">        <span class="comment">// router.MaxMultipartMemory = 8 &lt;&lt; 20  // 8 MiB</span></span><br><span class="line">        router.POST(<span class="string">&quot;/upload&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">            <span class="comment">// 单个文件</span></span><br><span class="line">            file, err := c.FormFile(<span class="string">&quot;f1&quot;</span>)</span><br><span class="line">            <span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">                c.JSON(http.StatusInternalServerError, gin.H&#123;</span><br><span class="line">                    <span class="string">&quot;message&quot;</span>: err.Error(),</span><br><span class="line">                &#125;)</span><br><span class="line">                <span class="keyword">return</span></span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            log.Println(file.Filename)</span><br><span class="line">            dst := fmt.Sprintf(<span class="string">&quot;C:/tmp/%s&quot;</span>, file.Filename)</span><br><span class="line">            <span class="comment">// 上传文件到指定的目录</span></span><br><span class="line">            c.SaveUploadedFile(file, dst)</span><br><span class="line">            c.JSON(http.StatusOK, gin.H&#123;</span><br><span class="line">                <span class="string">&quot;message&quot;</span>: fmt.Sprintf(<span class="string">&quot;&#x27;%s&#x27; uploaded!&quot;</span>, file.Filename),</span><br><span class="line">            &#125;)</span><br><span class="line">        &#125;)</span><br><span class="line">        router.Run()</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 多个文件上传</span></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">        router := gin.Default()</span><br><span class="line">        <span class="comment">// 处理multipart forms提交文件时默认的内存限制是32 MiB</span></span><br><span class="line">        <span class="comment">// 可以通过下面的方式修改</span></span><br><span class="line">        <span class="comment">// router.MaxMultipartMemory = 8 &lt;&lt; 20  // 8 MiB</span></span><br><span class="line">        router.POST(<span class="string">&quot;/upload&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">            <span class="comment">// Multipart form</span></span><br><span class="line">            form, _ := c.MultipartForm()</span><br><span class="line">            files := form.File[<span class="string">&quot;file&quot;</span>]</span><br><span class="line"></span><br><span class="line">            <span class="keyword">for</span> index, file := <span class="keyword">range</span> files &#123;</span><br><span class="line">                log.Println(file.Filename)</span><br><span class="line">                dst := fmt.Sprintf(<span class="string">&quot;C:/tmp/%s_%d&quot;</span>, file.Filename, index)</span><br><span class="line">                <span class="comment">// 上传文件到指定的目录</span></span><br><span class="line">                c.SaveUploadedFile(file, dst)</span><br><span class="line">            &#125;</span><br><span class="line">            c.JSON(http.StatusOK, gin.H&#123;</span><br><span class="line">                <span class="string">&quot;message&quot;</span>: fmt.Sprintf(<span class="string">&quot;%d files uploaded!&quot;</span>, <span class="built_in">len</span>(files)),</span><br><span class="line">            &#125;)</span><br><span class="line">        &#125;)</span><br><span class="line">        router.Run()</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<h2 id="六、gin重定向"><a href="#六、gin重定向" class="headerlink" title="六、gin重定向"></a>六、gin重定向</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// HTTP重定向</span></span><br><span class="line">    HTTP 重定向很容易。 内部、外部重定向均支持。</span><br><span class="line"></span><br><span class="line">    r.GET(<span class="string">&quot;/test&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">        c.Redirect(http.StatusMovedPermanently, <span class="string">&quot;http://www.sogo.com/&quot;</span>)</span><br><span class="line">    &#125;)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 路由重定向</span></span><br><span class="line">    路由重定向，使用HandleContext：</span><br><span class="line"></span><br><span class="line">    r.GET(<span class="string">&quot;/test&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">        <span class="comment">// 指定重定向的URL</span></span><br><span class="line">        c.Request.URL.Path = <span class="string">&quot;/test2&quot;</span></span><br><span class="line">        r.HandleContext(c)</span><br><span class="line">    &#125;)</span><br><span class="line">    r.GET(<span class="string">&quot;/test2&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">        c.JSON(http.StatusOK, gin.H&#123;<span class="string">&quot;hello&quot;</span>: <span class="string">&quot;world&quot;</span>&#125;)</span><br><span class="line">    &#125;)</span><br></pre></td></tr></table></figure>

<h2 id="七、gin路由与路由组"><a href="#七、gin路由与路由组" class="headerlink" title="七、gin路由与路由组"></a>七、gin路由与路由组</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1.</span> 普通路由</span><br><span class="line">    r.GET(<span class="string">&quot;/index&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;...&#125;)</span><br><span class="line">    r.GET(<span class="string">&quot;/login&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;...&#125;)</span><br><span class="line">    r.POST(<span class="string">&quot;/login&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;...&#125;)</span><br><span class="line"></span><br><span class="line">    此外，还有一个可以匹配所有请求方法的Any方法如下：</span><br><span class="line">    	r.Any(<span class="string">&quot;/test&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;...&#125;)</span><br><span class="line"></span><br><span class="line">    为没有配置处理函数的路由添加处理程序，默认情况下它返回<span class="number">404</span>代码，下面的代码为没有匹配到路由的请求都返回views/<span class="number">404.</span>html页面。</span><br><span class="line">    	r.NoRoute(<span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">                c.HTML(http.StatusNotFound, <span class="string">&quot;views/404.html&quot;</span>, <span class="literal">nil</span>)</span><br><span class="line">            &#125;)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="number">2.</span> 路由组</span><br><span class="line">    我们可以将拥有共同URL前缀的路由划分为一个路由组。习惯性一对&#123;&#125;包裹同组的路由，这只是为了看着清晰，你用不用&#123;&#125;包裹功能上没什么区别。</span><br><span class="line"></span><br><span class="line">        <span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">            r := gin.Default()</span><br><span class="line">            userGroup := r.Group(<span class="string">&quot;/user&quot;</span>)</span><br><span class="line">            &#123;</span><br><span class="line">                userGroup.GET(<span class="string">&quot;/index&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;...&#125;)</span><br><span class="line">                userGroup.GET(<span class="string">&quot;/login&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;...&#125;)</span><br><span class="line">                userGroup.POST(<span class="string">&quot;/login&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;...&#125;)</span><br><span class="line"></span><br><span class="line">            &#125;</span><br><span class="line">            shopGroup := r.Group(<span class="string">&quot;/shop&quot;</span>)</span><br><span class="line">            &#123;</span><br><span class="line">                shopGroup.GET(<span class="string">&quot;/index&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;...&#125;)</span><br><span class="line">                shopGroup.GET(<span class="string">&quot;/cart&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;...&#125;)</span><br><span class="line">                shopGroup.POST(<span class="string">&quot;/checkout&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;...&#125;)</span><br><span class="line">            &#125;</span><br><span class="line">            r.Run()</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">    路由组也是支持嵌套的，例如：</span><br><span class="line">        shopGroup := r.Group(<span class="string">&quot;/shop&quot;</span>)</span><br><span class="line">            &#123;</span><br><span class="line">                shopGroup.GET(<span class="string">&quot;/index&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;...&#125;)</span><br><span class="line">                shopGroup.GET(<span class="string">&quot;/cart&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;...&#125;)</span><br><span class="line">                shopGroup.POST(<span class="string">&quot;/checkout&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;...&#125;)</span><br><span class="line">                <span class="comment">// 嵌套路由组</span></span><br><span class="line">                xx := shopGroup.Group(<span class="string">&quot;xx&quot;</span>)</span><br><span class="line">                xx.GET(<span class="string">&quot;/oo&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;...&#125;)</span><br><span class="line">            &#125;</span><br><span class="line">    通常我们将路由分组用在划分业务逻辑或划分API版本时。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="number">3.</span> 路由原理</span><br><span class="line">    Gin框架中的路由使用的是httprouter这个库。</span><br><span class="line">    其基本原理就是构造一个路由地址的前缀树。</span><br></pre></td></tr></table></figure>

<h2 id="八、中间件"><a href="#八、中间件" class="headerlink" title="八、中间件"></a>八、中间件</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Gin框架允许开发者在处理请求的过程中，加入用户自己的钩子(Hook)函数，这个钩子函数就叫中间件，中间件适合处理一些公共的业务逻辑，比如登录认证、权限校验、数据分页、记录日志、耗时统计等。</span></span><br><span class="line"></span><br><span class="line"><span class="number">1.</span> 定义中间件</span><br><span class="line"><span class="comment">// Gin中的中间件必须是一个gin.HandlerFunc类型。例如我们像下面的代码一样定义一个统计请求耗时的中间件。</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">// StatCost 是一个统计耗时请求耗时的中间件</span></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">StatCost</span><span class="params">()</span> <span class="title">gin</span>.<span class="title">HandlerFunc</span></span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">            start := time.Now()</span><br><span class="line">            c.Set(<span class="string">&quot;name&quot;</span>, <span class="string">&quot;小王子&quot;</span>) <span class="comment">// 可以通过c.Set在请求上下文中设置值，后续的处理函数能够取到该值</span></span><br><span class="line">            <span class="comment">// 调用该请求的剩余处理程序</span></span><br><span class="line">            c.Next()</span><br><span class="line">            <span class="comment">// 不调用该请求的剩余处理程序</span></span><br><span class="line">            <span class="comment">// c.Abort()</span></span><br><span class="line">            <span class="comment">// 计算耗时</span></span><br><span class="line">            cost := time.Since(start)</span><br><span class="line">            log.Println(cost)</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="number">2.</span> 注册中间件</span><br><span class="line"><span class="comment">// 为全局路由注册</span></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">        <span class="comment">// 新建一个没有任何默认中间件的路由</span></span><br><span class="line">        r := gin.New()</span><br><span class="line">        <span class="comment">// 注册一个全局中间件</span></span><br><span class="line">        r.Use(StatCost())</span><br><span class="line"></span><br><span class="line">        r.GET(<span class="string">&quot;/test&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">            name := c.MustGet(<span class="string">&quot;name&quot;</span>).(<span class="keyword">string</span>) <span class="comment">// 从上下文取值</span></span><br><span class="line">            log.Println(name)</span><br><span class="line">            c.JSON(http.StatusOK, gin.H&#123;</span><br><span class="line">                <span class="string">&quot;message&quot;</span>: <span class="string">&quot;Hello world!&quot;</span>,</span><br><span class="line">            &#125;)</span><br><span class="line">        &#125;)</span><br><span class="line">        r.Run()</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 为某个路由单独注册</span></span><br><span class="line">    <span class="comment">// 给/test2路由单独注册中间件（可注册多个）</span></span><br><span class="line">        r.GET(<span class="string">&quot;/test2&quot;</span>, StatCost(), <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">            name := c.MustGet(<span class="string">&quot;name&quot;</span>).(<span class="keyword">string</span>) <span class="comment">// 从上下文取值</span></span><br><span class="line">            log.Println(name)</span><br><span class="line">            c.JSON(http.StatusOK, gin.H&#123;</span><br><span class="line">                <span class="string">&quot;message&quot;</span>: <span class="string">&quot;Hello world!&quot;</span>,</span><br><span class="line">            &#125;)</span><br><span class="line">        &#125;)</span><br><span class="line"><span class="comment">// 为路由组注册中间件</span></span><br><span class="line"><span class="comment">// 为路由组注册中间件有以下两种写法。</span></span><br><span class="line"></span><br><span class="line">    <span class="number">1.</span> 写法<span class="number">1</span>：</span><br><span class="line"></span><br><span class="line">        shopGroup := r.Group(<span class="string">&quot;/shop&quot;</span>, StatCost())</span><br><span class="line">        &#123;</span><br><span class="line">            shopGroup.GET(<span class="string">&quot;/index&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;...&#125;)</span><br><span class="line">            ...</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">    <span class="number">2.</span>写法<span class="number">2</span>：</span><br><span class="line"></span><br><span class="line">        shopGroup := r.Group(<span class="string">&quot;/shop&quot;</span>)</span><br><span class="line">        shopGroup.Use(StatCost())</span><br><span class="line">        &#123;</span><br><span class="line">            shopGroup.GET(<span class="string">&quot;/index&quot;</span>, <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;...&#125;)</span><br><span class="line">            ...</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="number">3.</span> 中间件注意事项</span><br><span class="line">    <span class="number">1.</span> gin默认中间件</span><br><span class="line"></span><br><span class="line">        gin.Default()默认使用了Logger和Recovery中间件，其中：</span><br><span class="line">        Logger中间件将日志写入gin.DefaultWriter，即使配置了GIN_MODE=release。</span><br><span class="line">        Recovery中间件会<span class="built_in">recover</span>任何<span class="built_in">panic</span>。如果有<span class="built_in">panic</span>的话，会写入<span class="number">500</span>响应码。</span><br><span class="line">        如果不想使用上面两个默认的中间件，可以使用gin.New()新建一个没有任何默认中间件的路由。</span><br><span class="line"></span><br><span class="line">    <span class="number">2.</span> gin中间件中使用goroutine</span><br><span class="line"></span><br><span class="line">    	当在中间件或handler中启动新的goroutine时，不能使用原始的上下文（c *gin.Context），必须使用其只读副本（c.Copy()）。</span><br><span class="line"></span><br><span class="line"><span class="number">4.</span> 代码演示</span><br><span class="line">    <span class="comment">// 这个也可以被称之为中间件</span></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">indexHandel</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">        c.JSON(http.StatusOK, gin.H&#123;</span><br><span class="line">            <span class="string">&quot;msg&quot;</span>: <span class="string">&quot;index&quot;</span>,</span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//定义一个m1中间件</span></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">m1</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">        fmt.Println(<span class="string">&quot;m1 in....&quot;</span>)</span><br><span class="line">        <span class="comment">// 计时</span></span><br><span class="line">        start := time.Now()</span><br><span class="line">        c.Next() <span class="comment">// 调用后续函数</span></span><br><span class="line">        <span class="comment">// c.Abort() // 组织调用后续函数</span></span><br><span class="line">        cost := time.Since(start)</span><br><span class="line">        fmt.Printf(<span class="string">&quot;cost: %#v&quot;</span>, cost)</span><br><span class="line">        fmt.Println(<span class="string">&quot;m1 out...&quot;</span>)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">m2</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">        fmt.Println(<span class="string">&quot;m2 in...&quot;</span>)</span><br><span class="line">        c.Next() <span class="comment">// 调用后续函数</span></span><br><span class="line">        <span class="comment">// c.Abort()</span></span><br><span class="line">        fmt.Println(<span class="string">&quot;m2 out...&quot;</span>)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">        r := gin.Default() <span class="comment">// 默认路由引擎</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">// r.Use(m1, m2, indexHandel) // 全局注册中间件</span></span><br><span class="line"></span><br><span class="line">        r.GET(<span class="string">&quot;/index&quot;</span>, m1, m2, indexHandel) <span class="comment">// 部分注册中间件</span></span><br><span class="line"></span><br><span class="line">        r.Run()</span><br><span class="line">    &#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>


            </div>

            <!-- Post Comments -->
            
    <!-- 使用 DISQUS_CLICK -->
<div id="disqus-comment">
    <div id="disqus_thread"></div>

<!-- add animation -->
<style>
	.disqus_click_btn {
            line-height: 30px;
            margin: 0;
            min-width: 50px;
            padding: 0 14px;
            display: inline-block;
            font-family: "Roboto", "Helvetica", "Arial", sans-serif;
            font-size: 14px;
            font-weight: 400;
            text-transform: uppercase;
            letter-spacing: 0;
            overflow: hidden;
            will-change: box-shadow;
            transition: box-shadow .2s cubic-bezier(.4, 0, 1, 1), background-color .2s cubic-bezier(.4, 0, .2, 1), color .2s cubic-bezier(.4, 0, .2, 1);
            outline: 0;
            cursor: pointer;
            text-decoration: none;
            text-align: center;
            vertical-align: middle;
            border: 0;
            background: rgba(158, 158, 158, .2);
            box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
            color: #fff;
            background-color: #7EC0EE;
            text-shadow: 0
        }
</style>
	
<div class="btn_click_load" id="disqus_bt"> 
    <button class="disqus_click_btn">点击查看评论</button>
</div>

<!--
<script type="text/javascript">
$('.btn_click_load').click(function() {
    /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
    var disqus_shortname = 'http-miccall-tech'; // required: replace example with your forum shortname

    /* * * DON'T EDIT BELOW THIS LINE * * */
    (function() {
      var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
      dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
      (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();

    document.getElementById('disqus_bt').style.display = "none";
});
</script>
-->
<script type="text/javascript">
    var disqus_config = function () {
        this.page.url = 'https://gitee.com/AmeX/amelin-ting.git/2020/01/01/Go---gin---%E8%BF%94%E5%9B%9E%E5%90%84%E7%A7%8D%E5%8F%82%E6%95%B0/';  // Replace PAGE_URL with your page's canonical URL variable
        this.page.identifier = 'https://gitee.com/AmeX/amelin-ting.git/2020/01/01/Go---gin---%E8%BF%94%E5%9B%9E%E5%90%84%E7%A7%8D%E5%8F%82%E6%95%B0/'; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
    };
</script>

<script type="text/javascript">
    $('.btn_click_load').click(function() {  //click to load comments
        (function() { // DON'T EDIT BELOW THIS LINE
            var d = document;
            var s = d.createElement('script');
            s.src = '//http-miccall-tech.disqus.com/embed.js';
            s.setAttribute('data-timestamp', + new Date());
            (d.head || d.body).appendChild(s);
        })();
        $('.btn_click_load').css('display','none');
    });
</script>
</div>
<style>
    #disqus-comment{
        background-color: #eee;
        padding: 2pc;
    }
</style>


        </div>
        <!-- Copyright 版权 start -->
                <div id="copyright">
            <ul>
                <li>&copy;Powered By <a target="_blank" rel="noopener" href="https://hexo.io/zh-cn/" style="border-bottom: none;">hexo</a></li>
                <li>Design: <a target="_blank" rel="noopener" href="http://miccall.tech " style="border-bottom: none;">miccall</a></li>
            </ul>
            
                <span id="busuanzi_container_site_pv">本站总访问量<span id="busuanzi_value_site_pv"></span>次</span>
			
        </div>
    </div>
</body>



 	
</html>
